﻿using ClewareWrapper.Invoke;

namespace ClewareWrapper
{
    public class Device
    {
        private ClewareManager _clewareManager;
        private int _deviceNumber;

        public Device(ClewareManager clewareManager, int deviceNumber)
        {
            _clewareManager = clewareManager;
            _deviceNumber = deviceNumber;
        }

        /// <summary>
        /// Version number of this device.
        /// </summary>
        public int Version
        {
            get
            {
                return _clewareManager.GetVersion(_deviceNumber);
            }
        }

        /// <summary>
        /// Device type. Possible values are defined in the USBtype_enum, eg. SWITCH1_DEVICE
        /// or TEMPERATURE2_DEVICE.
        /// </summary>
        public UsbType USBType
        {
            get
            {
                return _clewareManager.GetUSBType(_deviceNumber);
            }
        }

        /// <summary>
        /// Serial number of this device.
        /// </summary>
        public int SerialNumber
        {
            get
            {
                return _clewareManager.GetSerialNumber(_deviceNumber);
            }
        }

        /// <summary>
        /// When reading from and writing to the USB device failed several times, the device could
        /// be automatically searched and setup to the initial state.
        /// </summary>
        public int Recover()
        {
            return _clewareManager.Recover(_deviceNumber);
        }

        /// <summary>
        /// For later use.
        /// </summary>
        public System.IntPtr GetHandle()
        {
            return _clewareManager.GetHandle(_deviceNumber);
        }

        /// <summary>
        /// For later use. The return value is 0 in case of an error, else > 0.
        /// </summary>
        public int GetValue(System.IntPtr buf, int bufsize)
        {
            return _clewareManager.GetValue(_deviceNumber, buf, bufsize);
        }

        /// <summary>
        /// For later use. The return value is 0 in case of an error, else > 0..
        /// </summary>
        public int SetValue(System.IntPtr buf, int bufsize)
        {
            return _clewareManager.SetValue(_deviceNumber, buf, bufsize);
        }

        /// <summary>
        /// For later use. The return value is 0 in case of an error, else > 0.
        /// value: 0=off 7=medium 15=highlight
        /// </summary>
        public int SetLED(LedId Led, int value)
        {
            return _clewareManager.SetLED(_deviceNumber, Led, value);
        }

        /// <summary>
        /// Turns an USB-Switch on or off. The argument “Switch” defines which switch to set. If
        /// the argument “On” is 1, the switch is turned on. If “On” is 0, the switch is turned off. The
        /// return value is 0 in case of an error, else > 0.
        /// On: 0=off, 1=on
        /// </summary>
        public int SetSwitch(SwitchId Switch, int On)
        {
            return _clewareManager.SetSwitch(_deviceNumber, Switch, On);
        }

        /// <summary>
        /// Get the current switch state. The argument “Switch” defines which switch to get the status
        /// from. If the returned value is 1 if the switch is on and it is 0 otherwise. In case of an error,
        /// the return value is set to –1.
        /// On: 0=off, 1=on, -1=error
        /// </summary>
        public int GetSwitch(SwitchId Switch)
        {
            return _clewareManager.GetSwitch(_deviceNumber, Switch);
        }

        /// <summary>
        /// Get the current switch state. The argument “Switch” defines which switch to get the status
        /// from. If the returned value is 1 if the switch is on and it is 0 otherwise. The seqNum
        /// argument should be 0. In case of an error, the return value is set to –1.
        /// This command solves the problem that the USB data is buffered and maybe outdated.
        /// Using GetSeqSwitch will repeatedly get data from the buffer until the state represent the
        /// situation at the time of the call.*
        /// On: 0=off, 1=on, -1=error
        /// </summary>
        public int GetSeqSwitch(SwitchId Switch, int seqNum)
        {
            return _clewareManager.GetSeqSwitch(_deviceNumber, Switch, seqNum);
        }

        public int GetSwitchConfig(ref int switchCount, ref int buttonAvailable)
        {
            return _clewareManager.GetSwitchConfig(_deviceNumber, ref switchCount, ref buttonAvailable);
        }

        /// <summary>
        /// Calibration of a temperature device. The second parameter “Sollwert” is the correct
        /// temperature and the “Istwert” is the current value to be corrected. The return value is 0 in
        /// case of an error, else > 0.
        /// </summary>
        public int SetTempOffset(double Sollwert, double Istwert)
        {
            return _clewareManager.SetTempOffset(_deviceNumber, Sollwert, Istwert);
        }

        /// <summary>
        /// Request for the current temperature. This function will set the temperature and timeID to
        /// the actual values. The returned time is based on a device internal time. This time is used
        /// to assure that two requests deliver different times. At least one second must separate
        /// adjacent calls. If several requests returns the same time, the device may be in trouble and
        /// a reset is necessary. This must be initiated by calling the “ResetDevice” function. The
        /// return value is 0 in case of an error, else > 0.
        /// </summary>
        public int GetTemperature(ref double Temperature, ref int timeID)
        {
            return _clewareManager.GetTemperature(_deviceNumber, ref Temperature, ref timeID);
        }

        /// <summary>
        /// Request for the current humidity. This function will set the humidity and timeID to the
        /// actual values. The returned time is based on a device internal time. This time is used to
        /// assure that two requests deliver different times. At least two seconds must separate
        /// adjacent calls. The return value is 0 in case of an error, else > 0.
        /// </summary>
        public int GetHumidity(ref double Humidity, ref int timeID)
        {
            return _clewareManager.GetHumidity(_deviceNumber, ref Humidity, ref timeID);
        }

        /// <summary>
        /// Reset a Cleware device. The return value is 0 in case of an error, else > 0. If the device is
        /// a temperature or humidity sensor, the command causes a hardware reset of the sensor.
        /// Other devices will do a cold start when disconnected for a short time.
        /// </summary>
        public int ResetDevice()
        {
            return _clewareManager.ResetDevice(_deviceNumber);
        }

        /// <summary>
        /// The USB-Humidity must get a start command to enter the measuring loop. This command
        /// must be send after a reset or when the commands SetValue oder GetValue were used.
        /// When StartDevice is called for other devices it will be ignored. In case of an error, the
        /// return value ist 0, otherwise != 0.
        /// </summary>
        public int StartDevice()
        {
            return _clewareManager.StartDevice(_deviceNumber);
        }

        /// <summary>
        /// Send a life signal to an USB-Wathdog. The time until the next life signal must be detected
        /// is supplied in minutes. If “time1” is –1 the device is activated immediately (USBAutoReset).
        /// The return value is 0 in case of an error, else > 0.
        /// If the device is an USB-AutoReset “time2” defines the time distance for the secondary
        /// reset for cases the first reset will not restart the PC up to point where life signals will be
        /// send again. The value is defined in minutes and could be in the range 0 – 255. If the value
        /// is 0, the secondary reset is turned off.
        /// If the device is an USB-WatchLight, the green light is turned on when the CalmWatchdog
        /// command is executed. The argument “time1” defines the offset in seconds until the red
        /// light is turned on. The yellow light is turned on after “time2” seconds.
        /// </summary>
        public int CalmWatchdog(int minutes, int minutes2restart)
        {
            return _clewareManager.CalmWatchdog(_deviceNumber, minutes, minutes2restart);
        }

        /// <summary>
        /// If the device is configured as an USB-Watchdog or USB-AutoReset, this counter reflects
        /// how often a reset was done by an USB command.
        /// </summary>
        public int GetManualOnCount()
        {
            return _clewareManager.GetManualOnCount(_deviceNumber);
        }

        public int GetManualOnTime()
        {
            return _clewareManager.GetManualOnTime(_deviceNumber);
        }

        /// <summary>
        /// Get the “turned on by USB command” counter (USB-Switch version 15 and higher). In
        /// case of an error –1 will be returned. If the device is configured as an USB-Watchdog or
        /// USB-AutoReset, this counter reflects how often a reset was done by missing the USB life
        /// signal.
        /// </summary>
        public int GetOnlineOnCount()
        {
            return _clewareManager.GetOnlineOnCount(_deviceNumber);
        }

        /// <summary>
        /// These commands are used with an USB-Switch equiped with a button for manual
        /// switching. In case of an error –1 will be returned.  
        /// </summary>
        public int GetOnlineOnTime()
        {
            return _clewareManager.GetOnlineOnTime(_deviceNumber);
        }

        /// <summary>
        /// All input channels of the devices USB-Contact and USB-IO16 could be scanned with the
        /// command “GetMultiSwitch”. The argument “mask” indicates the channels which changes
        /// the values since the last call of GetMultiSwitch. Channel 0 is the least significant bit
        /// (LSB). The argument shows the current status of all channels. The argument “seqNum”
        /// should be set to 0.
        /// </summary>
        public int GetMultiSwitch(uint param2, ref int mask, uint param4, ref int value, int seqNumber)
        {
            return _clewareManager.GetMultiSwitch(_deviceNumber, param2, ref mask, param4, ref value, seqNumber);
        }

        /// <summary>
        /// All output channels of the USB-IO16 will be set with the command “SetMultiSwitch”.
        /// The argument “value” holds the new state of the channels. Channel 0 is the least
        /// significant bit (LSB).
        /// </summary>
        public int SetMultiSwitch(uint param2, int value)
        {
            return _clewareManager.SetMultiSwitch(_deviceNumber, param2, value);
        }

        /// <summary>
        /// The configuration of the USB-IO16 is defined with the command SetMultiConfig. Every
        /// channel is assigned a bit in the direction argument. Channel 0 is the least significant bit
        /// (LSB). If the bit is 0 the channel is configured as an input, otherwise as an output.
        /// </summary>
        public int SetMultiConfig(uint param2, int directions)
        {
            return _clewareManager.SetMultiConfig(_deviceNumber, param2, directions);
        }

        /// <summary>
        /// The counter value of the USB-Counteer is requested.
        /// </summary>
        public int GetCounter(int counter)
        {
            return _clewareManager.GetCounter(_deviceNumber, counter);
        }

        /// <summary>
        /// For internal purposes.
        /// </summary>
        public int SyncDevice(uint param2, int mask)
        {
            return _clewareManager.SyncDevice(_deviceNumber, param2, mask);
        }

        public int GetMultiConfig()
        {
            return _clewareManager.GetMultiConfig(_deviceNumber);
        }

        public int IsAmpel()
        {
            return _clewareManager.IsAmpel(_deviceNumber);
        }

        public int IsSolidState()
        {
            return _clewareManager.IsSolidState(_deviceNumber);
        }

        public int IsWatchdogInvert()
        {
            return _clewareManager.IsWatchdogInvert(_deviceNumber);
        }
    }
}
